home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / d_pc32.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  29KB  |  1,205 lines

  1. /*---------------------------------------------------------------------------*/
  2. /*  IBM PC Driver 1.0 (TURBO  C) , for GLE V3.0                              */
  3. /*---------------------------------------------------------------------------*/
  4. /* This version might be too "fat" for Turbo C due to path routines          */
  5. /*---------------------------------------------------------------------------*/
  6.  
  7. #include "all.h"
  8. #include <bios.h>
  9. #include <math.h>
  10. #include "core.h"
  11. #include "mygraph.h"
  12. #include "mydev.h"
  13.  
  14. #ifdef __GNUC__
  15. #  ifndef __linux__
  16. #    include <pc.h>
  17. #  endif
  18. #  include <grx.h>
  19. #  include <bccgrx.h>
  20. #else
  21. #  include <conio.h>
  22. #  include <graphics.h>
  23. #endif
  24.  
  25. int ingraphmode;
  26. extern int gunit;
  27. extern struct gmodel g;
  28. /*---------------------------------------------------------------------------*/
  29. #define pi 3.141592653
  30. #define true (!false)
  31. #define BLACKANDWHITE 1
  32. #define false 0
  33. #define dbg if ((gle_debug & 64)>0)
  34. #define stop if ((gle_debug & 128)>0) return
  35. extern int gle_debug;
  36. int incap=true;
  37.  
  38.  
  39. #ifndef __linux__
  40.   int getch(void);
  41.   int kbhit(void);
  42. #else
  43.   #undef kbhit
  44.   #define getch getchar
  45. #endif
  46.  
  47. int d_prompts(void);
  48. /*---------------------------------------------------------------------------*/
  49. /* The global variables for the PC screen driver */
  50. /*-----------------------------------------------*/
  51.  
  52. int i,l,j,ix,iy;
  53. double f;
  54.  
  55.  
  56. #define gerr() i = graphresult(); if (i!=0) printf("Graph error: %s \n",grapherrormsg(i));
  57.  
  58. #define xsizecm 32.0
  59. #define ysizecm 24.0
  60.  
  61. #define sx(v) ( (int) ((v) * d_xscale)+1)
  62. #define sy(v) ( d_maxy - ((int) ((v) * d_yscale)))
  63. #define rx(v) ( (int) ((v) * d_xscale)+1)
  64. #define ry(v) ( d_maxy - ((int) ((v) * d_yscale)))
  65. #define textmode() {getch(); restorecrtmode();}
  66. #define graphmode() {getch(); setgraphmode(d_graphmode);}
  67. #define gon  if ((gle_debug & 256) > 0) graphmode()
  68. #define goff if ((gle_debug & 256) > 0) textmode()
  69.  
  70. double d_scale, d_xscale, d_yscale;
  71. int d_graphmode;
  72. int d_fillstyle,d_fillcolor;
  73. int d_lstyle,d_lwidth,d_pat;
  74. int d_maxy;
  75.  
  76. int d_zzline(double cx,double cy,double zx,double zy);
  77. int addline(char *s);
  78. int getwhite(void);
  79.  
  80. /* path routines */
  81. void path_move(int x, int y);
  82. void path_line(int x, int y);
  83. void path_close(void);
  84. void path_fill(void);
  85. void path_newpath(void);
  86. void path_stroke(void);
  87.  
  88.  
  89. int getwhite()
  90. {
  91.     int i;
  92.     i = getmaxcolor();
  93.     if (i>15) i = 15;
  94.     return i;
  95. }
  96.  
  97. d_devcmd(char *s)
  98. {}
  99.  
  100. int undxy(int dx, int dy, double *x, double *y);
  101. undxy(int dx, int dy, double *x, double *y)
  102. {
  103.     double ddx,ddy;
  104.     char buff[80];
  105.     ddx = (dx)/d_xscale;
  106.     ddy = (dy - d_maxy) / -d_yscale;
  107.     g_undev(ddx,ddy,x,y);
  108. }
  109. dxy(double x, double y, int *dx, int *dy)
  110. {
  111.     static double fx,fy;
  112.     g_dev(x,y,&fx,&fy);
  113.     *dx = sx(fx);
  114.     *dy = sy(fy);
  115. }
  116. rxy(double x, double y, int *dx, int *dy)
  117. {
  118.     static double fx,fy,zx,zy;
  119.     g_dev(x,y,&fx,&fy);
  120.     g_dev(0.0,0.0,&zx,&zy);
  121.     *dx = (int) ( (fx-zx) * d_xscale +1);
  122.     *dy = (int) ( (fy-zy) * d_yscale);
  123. }
  124. /*---------------------------------------------------------------------------*/
  125. d_dfont(char *c)
  126. {
  127.     /* only used for the DFONT driver which builds fonts */
  128. }
  129. /*---------------------------------------------------------------------------*/
  130. static char lastline[80];
  131. d_message(char *s)
  132. {
  133.     static int single_step;
  134.     int oldcolor,oldx,oldy;
  135.     if (ingraphmode) {
  136.         oldx = getx(); oldy = gety();
  137.         oldcolor = getcolor();
  138.         setfillstyle(1,BLACK);
  139.         setcolor(WHITE);
  140.         bar(1,getmaxy()-19,getmaxx(),getmaxy());
  141.         settextstyle(0,0,0);
  142.         settextjustify(LEFT_TEXT,BOTTOM_TEXT);
  143.         moveto(4,getmaxy()-10);
  144.         if (strlen(lastline)>0) outtext(lastline);
  145.         moveto(4,getmaxy()-2);
  146.         outtext(s);
  147.         ncpy(lastline,s,78);
  148.         setcolor(oldcolor);
  149.         setfillstyle(d_fillstyle,d_fillcolor);
  150.         moveto(oldx,oldy);
  151.         if (single_step) {
  152.             if (getch()=='g') single_step = false;
  153.         }
  154.         if (kbhit()) {
  155.             if ((bioskey(1) & 0xff) != 27) {
  156.              if (getch()=='s') single_step = true;
  157.              while (kbhit()) getch();
  158.              getch();
  159.             }
  160.         }
  161.     } else {
  162.         printf("%s\n",s);
  163.     }
  164. }
  165. /*---------------------------------------------------------------------------*/
  166. d_source(char *s)
  167. {
  168.     s=s;
  169. }
  170. /*---------------------------------------------------------------------------*/
  171. d_get_type(char *t)
  172. {
  173.     strcpy(t,"INTERACTIVE, PC");
  174. }
  175. /*---------------------------------------------------------------------------*/
  176. d_set_path(int onoff)
  177. {}
  178. /*---------------------------------------------------------------------------*/
  179. d_newpath()
  180. {
  181.     path_newpath();
  182. }
  183. int svga_mode=grError;
  184. int huge detect_svga()
  185. {
  186.   gprint("Loading USER BGI driver \n");
  187.   return svga_mode;
  188. }
  189. void add_svga(void)
  190. {
  191.     int g_error;
  192.     char *s,buff[80],sname[40];
  193.     s = getenv("GLE_ADDBGI");
  194.     if (s==NULL) return;
  195.     strcpy(buff,s);
  196.     s = strtok(buff," .");
  197.     if (s==NULL) {gprint("Expecting mode.name, e.g. 3.svga256,  found {%s} \n",buff); return;}
  198.     svga_mode = atoi(s);
  199.     s = strtok(NULL," .");
  200.     if (s==NULL) {gprint("Expecting 'mode.name' , e.g. 3.svga256,  found {%s} \n",buff); return;}
  201.     strcpy(sname,s);
  202.        #ifndef __GNUC__         /* no BGI */ 
  203.     installuserdriver(sname,detect_svga);
  204.        #endif
  205.     g_error = graphresult();
  206.     if (g_error<0) {
  207.         gprint("InstallUserDriver error %s\n",grapherrormsg(g_error));
  208.         text_inkey();
  209.     }
  210. }
  211.  
  212. /*---------------------------------------------------------------------------*/
  213. char *bgidir(void);
  214. d_open(double width, double height)
  215. {
  216.     static int g_driver,g_error;
  217.     double f;
  218.     static int doneopen;
  219.        #ifdef __GNUC__
  220.     char *buffa, *buffb, *buffc;
  221.        #endif        
  222.  
  223.     if (!doneopen) 
  224.      {
  225.            #ifndef DJ
  226.         add_svga();
  227.            #endif
  228.         doneopen = true;
  229.  
  230.            /* detectgraph(&g_driver, &d_graphmode);
  231.         if (g_driver<0) {
  232.             printf("No graphics hardware detected !!!!! \n");
  233.             gle_abort("Could not load BGI graphics\n");
  234.         }  
  235.            */
  236.         g_driver = DETECT;
  237.            #ifndef __GNUC__
  238.         initgraph(&g_driver,&d_graphmode,bgidir());
  239.            #else
  240.         buffa = getenv("GLE32WIDTH");
  241.         buffb = getenv("GLE32HEIGHT");
  242.         buffc = getenv("GLE32COLORS");
  243.         if ( ( buffa != NULL ) && ( buffb != NULL ) && ( buffc != NULL ) )
  244.           {
  245.            g_driver = DETECT;
  246.            set_BGI_mode_whc(&g_driver, &d_graphmode, atoi(buffa), atoi(buffb), atoi(buffc));
  247.            initgraph(&g_driver,&d_graphmode,getenv("GLE32FONT"));
  248.           }
  249.         else
  250.           { 
  251.            detectgraph(&g_driver, &d_graphmode);
  252.            initgraph(&g_driver,&d_graphmode,getenv("GLE32FONT"));
  253.           }
  254.            #endif                
  255.      } 
  256.     else
  257.         setgraphmode(d_graphmode);
  258.         
  259.     g_error = graphresult();
  260.     if (g_error<0)
  261.       {
  262.        printf("Init graph error %s\n",grapherrormsg(g_error));
  263.        ingraphmode = false; text_inkey(); gle_abort("Init graph error\n");
  264.       }
  265.        #ifndef __GNUC__
  266.     /* this makes mouse work on herc card */
  267.     if (g_driver==HERCMONO)
  268.         pokeb(0x40,0x49,6);
  269.        #endif
  270.     ingraphmode = true;
  271.     /* Get largest rectangle we can fit on the screen */
  272.     d_scale = xsizecm / width;
  273.     f = ysizecm / height;
  274.     if (f<d_scale) d_scale = f;
  275.  
  276.     d_xscale = d_scale * (getmaxx()-2) / xsizecm; /* Device Scale X, Device Scale y */
  277.     d_yscale = d_scale * (getmaxy()-22) / ysizecm;
  278.     d_maxy = getmaxy()-21;
  279.     g.userwidth = width;
  280.     g.userheight = height;
  281. }
  282. /*---------------------------------------------------------------------------*/
  283. d_tidyup()
  284. {
  285.     if (ingraphmode) {
  286.         gprint("AARRRrrrrgg,  Watch out I'm dying!!!\n");
  287.         d_close();
  288.     }
  289. }
  290. void mouseloc(int column,int  row);     /* set location of mouse cursor */
  291. int draw_boxline(int d_imde,double x1,double y1,double x2,double y2);
  292. int d_get_click(double *x, double *y, int *click);
  293. int d_get_point(double *x, double *y, int *click);
  294. void mousecursor( int toggle);
  295. int cross_hair(double x, double y);
  296. int mousecheck(void);
  297. double mouse_x,mouse_y,gridstep;
  298. int boxed_text,ismouse;
  299. int d_imde;
  300. double d_mousex,d_mousey;
  301.  
  302.  
  303. int gridit(double *x,double *y);
  304. gridit(double *x,double *y)
  305. {
  306.     *x = floor(*x/gridstep + .5) * gridstep;
  307.     *y = floor(*y/gridstep + .5) * gridstep;
  308. }
  309. int d_prompts(void)
  310. {
  311.      if (d_imde==1) d_message("Click on position for TEXT");
  312.      if (d_imde==2) d_message("Click on position for LINE");
  313.      if (d_imde==3) d_message("Click on position for BOX");
  314.      d_message("t=text l=line b=box o=bOxed_text c=Click u=penUp f=finer g=greater ESC=Exit");
  315. }
  316. d_cursor_toggle(void)
  317. {
  318.     static int onoff=0;
  319.     onoff = !onoff;
  320.     setcolor(getwhite());
  321.     setwritemode(XOR_PUT);
  322.     if (ismouse) mousecursor(onoff); else cross_hair(d_mousex,d_mousey);
  323.     setcolor(0);
  324.     setwritemode(COPY_PUT);
  325. }
  326. d_xor(void)
  327. {
  328.     setcolor(getwhite());
  329.     setwritemode(XOR_PUT);
  330. }
  331. wait_for_return()
  332. {
  333.     int exitlp=false,click=0,clickex=0,oldmode;
  334.     double x1,y1,x2,y2,nx,ny;
  335.     char buff1[90],buff2[90];
  336. /* valid commands are */
  337. /* t = text, l = line, u=penup, b=box, o=bOxed text, f = finer, g = greater */
  338.     d_imde = 2;
  339.     if (d_mousex==0) {
  340.         d_mousex = g.userwidth/2;
  341.         d_mousey = g.userheight/2;
  342.     }
  343.     if (mousecheck()) ismouse = true;
  344.     if (!ismouse) gridstep = 1;
  345.     if (gridstep==0) gridstep = .1;
  346.     d_cursor_toggle();
  347.     for (;;) {
  348.      d_prompts();
  349.      oldmode = d_imde;
  350.      d_get_click(&x1,&y1,&click); if (click==3) goto aborting;
  351.      if (oldmode!=d_imde) goto next_one;
  352.      gridit(&x1,&y1);
  353.      if (d_imde==1) {
  354.         d_message("Enter the text at the top of the screen");
  355.         d_get_line(buff1,&click);
  356.         if (click==3) goto next_one;
  357.         sprintf(buff2,"amove %g %g ",x1,y1); addline(buff2);
  358.         if (boxed_text) addline("begin box add .2");
  359.         sprintf(buff2,"text %s",buff1);
  360.         addline(buff2);
  361.         if (boxed_text) addline("end box");
  362.         g_move(x1,y1);
  363.         g_text(buff1);
  364.         if (d_imde==1) d_imde = 2;
  365.         goto next_one;
  366.      }
  367.      sprintf(buff1,"amove %g %g",x1,y1); addline(buff1);
  368. poly:    d_xor();
  369.      draw_boxline(d_imde,x1,y1,x1,y1);
  370.      x2 = x1; y2 = y1;
  371.      if (d_imde==2 || d_imde==3) {
  372.       oldmode = d_imde;
  373.       for (click=0;click==0 && (d_imde==oldmode);) {
  374.         d_get_point(&nx,&ny,&click);
  375.         if (x2!=nx || y2!=ny) {
  376.           d_cursor_toggle();
  377.           d_xor();
  378.           draw_boxline(oldmode,x1,y1,x2,y2);
  379.           draw_boxline(oldmode,x1,y1,nx,ny);
  380.           d_cursor_toggle();
  381.         }
  382.         delay(10);
  383.         x2 = nx; y2 = ny;
  384.       }
  385.       d_cursor_toggle();
  386.       d_xor();
  387.       draw_boxline(oldmode,x1,y1,nx,ny);
  388.       if (click==1 && d_imde==oldmode) {
  389.         gridit(&x2,&y2);
  390.         setcolor(0);
  391.         setwritemode(COPY_PUT);
  392.         draw_boxline(d_imde,x1,y1,x2,y2);
  393.         if (d_imde==2) {
  394.             sprintf(buff1,"rline %g %g",x2-x1,y2-y1); addline(buff1);
  395.             x1 = x2; y1 = y2;
  396.             d_cursor_toggle();
  397.             if (click==1) goto poly;
  398.         }
  399.         if (d_imde==3) {
  400.             sprintf(buff1,"box %g %g ",x2-x1,y2-y1); addline(buff1);
  401.         }
  402.       }
  403.       d_cursor_toggle();
  404.      }
  405. next_one:;
  406.     setcolor(0);
  407.     setwritemode(COPY_PUT);
  408.     }
  409. aborting:;
  410.     d_cursor_toggle();
  411. }
  412. draw_boxline(int d_imde,double x1,double y1,double x2,double y2)
  413. {
  414.     if (d_imde==2) {
  415.         g_move(x1,y1);
  416.         g_line(x2,y2);
  417.     } else {
  418.         g_move(x1,y1);
  419.         g_box_stroke(x1,y1,x2,y2);
  420.     }
  421. }
  422. d_get_click(double *x, double *y, int *click)
  423. {
  424.     for (;;) {
  425.      d_get_point(x,y,click);
  426.      if (*click>0) return;
  427.      delay(10);
  428.     }
  429. }
  430. #include "edt.h"
  431. int ddgets(char *s);
  432. d_get_line(char *s,int *click)
  433. {
  434.     if (ddgets(s)) *click = 3;
  435.     else *click = 0;
  436. }
  437. ddgets(char *s)
  438. {
  439.     int c,cx=0;
  440.     char mbuff[80];
  441.     *s = 0;
  442.     bottom_line(s);
  443.     for (;;) {
  444.      c = text_inkey();
  445.      switch (c) {
  446.       case eescape: /* ESCAPE */
  447.       case equit: /* control c */
  448.         return true;
  449.       case ereturn: /* carriage return */
  450.         return false;
  451.       case edelete: /* delete */
  452.         if (strlen(s)==0) break;
  453.         if (cx<1) break;
  454.         ncpy(mbuff,s,cx-1);
  455.         strcat(mbuff,s + cx);
  456.         strcpy(s,mbuff);
  457.         cx--;
  458.         bottom_line(s);
  459.         break;
  460.       default: /* normal key */
  461.         if (c<26  && c!=9) {fner("Key has no affect"); break;}
  462.         if (c>200)  fner("Unimplemented command");
  463.         else {
  464.             ncpy(mbuff,s,cx);
  465.             mbuff[cx] = c; mbuff[cx+1] = 0;
  466.             strcat(mbuff,s + cx);
  467.             strcpy(s,mbuff);
  468.             bottom_line(s);
  469.             cx++;
  470.         }
  471.         break;
  472.        }
  473.      }
  474. }
  475. bottom_line(char *s)
  476. {
  477.     setfillstyle(1,BLACK);
  478.     setcolor(WHITE);
  479.     bar(1,getmaxy()-9,getmaxx(),getmaxy());
  480.     settextstyle(0,0,0);
  481.     settextjustify(LEFT_TEXT,BOTTOM_TEXT);
  482.     moveto(4,getmaxy()-2);
  483.     outtext("Enter text? ");
  484.     outtext(s);
  485.     setcolor(0);
  486. }
  487.  
  488. d_get_point(double *x, double *y, int *click)
  489. {
  490.     int i,c,ix,iy,oldmode;
  491.  
  492.     if (ismouse) {
  493.         undxy(mousecol(),mouserow(),x,y);
  494.         d_mousex = *x; d_mousey = *y;
  495.     } else {
  496.         *x = d_mousex;
  497.         *y = d_mousey;
  498.     }
  499.     *click = 0;
  500.     if (kbhit()) {
  501.         oldmode = d_imde;
  502.         c = text_inkey();
  503.         c = tolower(c);
  504.         switch (c) {
  505.           case 'l': /* line */
  506.             d_imde = 2;  break;
  507.           case 'b': /* box */
  508.             d_imde = 3;  break;
  509.           case 't': /* text */
  510.             d_imde = 1;  boxed_text = false; break;
  511.           case 'o': /* boxed text */
  512.             d_imde = 1;
  513.             boxed_text = true; break;
  514.           case 'f': /* finer grid */
  515.             gridstep = gridstep / 10; break;
  516.           case 'g': /* greater grid */
  517.             gridstep *= 10; break;
  518.           case ereturn: /* return, finished */
  519.           case eescape:
  520.             *click = 3; break;
  521.           case 'u':  /* pen up */
  522.             *click = 2; break;
  523.           case 'd': /* pen down */
  524.           case 'c': /* click */
  525.             *click = 1; break;
  526.           case eup: /* Move cursor up 1 grid step */
  527.             *y += gridstep; break;
  528.           case edown:
  529.             *y -= gridstep; break;
  530.           case eright:
  531.             *x += gridstep; break;
  532.           case eleft:
  533.             *x -= gridstep; break;
  534.         }
  535.         if (oldmode!=d_imde) *click = 2;
  536.     }
  537.     if (ismouse) {
  538.         i = mouseclick();
  539.         if (i>0) *click = i;
  540.         undxy(mousecol(),mouserow(),x,y);
  541.     } else {
  542.         gridit(x,y);
  543.     }
  544.     if (*x != d_mousex || *y != d_mousey) {
  545.         if (ismouse) {
  546.             dxy(d_mousex,d_mousey,&ix,&iy);
  547.             mouseloc(ix,iy);
  548.         } else {
  549.             d_cursor_toggle();
  550.             d_mousex = *x;
  551.             d_mousey = *y;
  552.             d_cursor_toggle();
  553.         }
  554.     }
  555. }
  556. cross_hair(double x,double y)
  557. {
  558.     int ix,iy;
  559.     dxy(x,y,&ix,&iy);
  560.     moveto(ix,iy-10);
  561.     lineto(ix,iy+10);
  562.     moveto(ix-10,iy);
  563.     lineto(ix+10,iy);
  564. }
  565. d_close()
  566. {
  567.     stop;gon;
  568.     if (ingraphmode == false) return;
  569.     g_flush();
  570.     d_message("Press <RETURN> to continue");
  571.     lastline[0] = 0;
  572.     if (kbhit()) getch();
  573.     wait_for_return();
  574.     ingraphmode = false;
  575.     restorecrtmode();
  576. }
  577. /*---------------------------------------------------------------------------*/
  578. d_set_line_cap(int i)
  579. {
  580.     i++;
  581. }
  582. /*---------------------------------------------------------------------------*/
  583. d_set_line_join(int i)
  584. {
  585.     i++;
  586. }
  587. /*---------------------------------------------------------------------------*/
  588. d_set_line_miterlimit(double d)
  589. {
  590.     i++;
  591. }
  592. /*---------------------------------------------------------------------------*/
  593. d_set_line_width(double w)
  594. {
  595.     stop;
  596.     d_lwidth = 1;
  597.     if (w>.099) d_lwidth = 3;
  598.     setlinestyle(d_lstyle,d_pat,d_lwidth);
  599.     gerr();goff;
  600. }
  601. /*---------------------------------------------------------------------------*/
  602. d_set_line_styled(double dd)
  603. {}
  604. d_set_line_style(char *s)
  605. {
  606.     static char *defline[] = {"","","12","41","14","92",
  607.     "1282","9229","4114","54"};
  608.     int i, j, nblack, nwhite, pat;
  609.     char *ss;
  610.     stop;gon;
  611.  
  612.     if (strlen(s)==1)  s = defline[*s-'0'];
  613.     if (strcmp(s,"")==0) {
  614.         d_lstyle = SOLID_LINE;
  615.         d_pat = 0;
  616.         setlinestyle(d_lstyle,0,d_lwidth);
  617.     } else {
  618.         ss = s;
  619.         pat = 0;                 /* make a 16 bit pattern from digits */
  620.         for (i=15; i>=0;) {
  621.         nblack = *s - '0';
  622.         s++;
  623.         for (j=0; j<nblack; j++) {
  624.             pat = pat | (1L << i);
  625.             i--;
  626.         }
  627.         if (*s == 0)  s = ss;   /* if odd number of digits, repeat */
  628.         nwhite = *s - '0';
  629.         s++;
  630.         i = i - nwhite;
  631.         if (*s == 0)  s = ss;
  632.         }
  633.         d_lstyle = USERBIT_LINE;
  634.         d_pat = pat;
  635.         setlinestyle(d_lstyle,pat,d_lwidth);
  636.     }
  637.     gerr();goff;
  638. }
  639. /*---------------------------------------------------------------------------*/
  640. int in_font;
  641. d_fill()
  642. {
  643.     if (in_font)
  644.         path_stroke();/* don't fill fonts, path filling isn't perfect */
  645.     else
  646.         path_fill();
  647. }
  648. /*---------------------------------------------------------------------------*/
  649. d_fill_ary(int nwk,double (*wkx)[],double (*wky)[])
  650. {
  651.     int i;
  652. /*  fprintf(psfile,"%g %g moveto \n",(*wkx)[0],(*wky)[0]);
  653.     for (i=1;i<nwk;i++)
  654.         fprintf(psfile,"%g %g l \n",(*wkx)[i],(*wky)[i]);
  655. */
  656. }
  657. d_line_ary(int nwk,double (*wkx)[],double (*wky)[])
  658. {
  659.     int i;
  660.     stop;gon;
  661.     dxy( (*wkx)[0], (*wky)[0], &ix, &iy);
  662.     moveto(ix,iy);
  663.     for (i=1;i<nwk;i++) {
  664.         dxy( (*wkx)[i], (*wky)[i], &ix, &iy);
  665.         lineto(ix,iy);
  666.     }
  667.     gerr();goff;
  668. }
  669. /*---------------------------------------------------------------------------*/
  670. d_stroke()
  671. {
  672.     path_stroke();
  673. }
  674. /*---------------------------------------------------------------------------*/
  675. d_clip()
  676. {
  677. }
  678. /*---------------------------------------------------------------------------*/
  679. d_set_matrix(double newmat[3][3])
  680. {
  681. }
  682. /*---------------------------------------------------------------------------*/
  683. d_move(double zx,double zy)
  684. {
  685. }
  686. #ifdef DJ       /* to draw markers in surface */
  687.  d_move_really(float zx, float zy)
  688.  {
  689.      moveto(sx(zx),sy(zy));
  690.  }
  691.  int draw_circle(void)
  692.  {
  693.      circle(getx(), gety(), 4);
  694.  }
  695. #endif
  696. /*---------------------------------------------------------------------------*/
  697. d_reverse()     /* reverse the order of stuff in the current path */
  698. {
  699. }
  700. /*---------------------------------------------------------------------------*/
  701. d_closepath()
  702. {
  703.     if (g.inpath==true) {
  704.         path_close();
  705.         return;
  706.     }
  707.     g_line(g.closex,g.closey);
  708. }
  709. /*---------------------------------------------------------------------------*/
  710. int dunx1,dunx2,duny1,duny2;
  711. d_unline()
  712. {
  713.     setcolor(getwhite());
  714.     moveto(dunx1,duny1);
  715.     lineto(dunx2,duny2);
  716. }
  717. d_zzline(double cx,double cy,double zx,double zy)
  718. {
  719.     static int ux,uy,ix,iy;
  720.     dxy(cx,cy,&ux,&uy);
  721.     dunx1 = ux; duny1 = uy;
  722.     dxy(zx,zy,&ix,&iy);
  723.     setcolor(0);
  724.     moveto(ux,uy);
  725.     lineto(ix,iy);
  726.     dunx2 = ix; duny2 = iy;
  727. }
  728.  
  729. d_line(double zx,double zy)
  730. {
  731.     static int ux,uy;
  732.     dxy(g.curx,g.cury,&ux,&uy);
  733.     dxy(zx,zy,&ix,&iy);
  734.     if (g.inpath==true)
  735.            {
  736.         if (!g.xinline) 
  737.             path_move(ux,uy);
  738.         path_line(ix,iy);
  739.         return;
  740.            }
  741.     line(ux,uy,ix,iy);
  742.     dunx2 = ix; duny2 = iy;
  743. }
  744. /*---------------------------------------------------------------------------*/
  745. d_clear()
  746. {
  747.     double width,height;
  748.     int x1,y1,x2,y2;
  749.     width = g.userwidth;
  750.     height = g.userheight;
  751.     stop;
  752.     d_lstyle = SOLID_LINE;
  753.     d_pat = 0;
  754.     d_lwidth = 1;
  755.     setgraphmode(d_graphmode);
  756.  
  757.     /* now draw bounding box of screen */
  758.     x1 = 0;
  759.     y1 = d_maxy-height*d_yscale -1;
  760.     x2 = width*d_xscale+2;
  761.     y2 = d_maxy+1;
  762.     setfillstyle(1,getwhite());
  763.     bar(x1,y1,x2,y2);
  764.     setcolor(BLACK);
  765.     goff;
  766. }
  767. /*---------------------------------------------------------------------------*/
  768. d_flush()
  769. {
  770. }
  771. /*---------------------------------------------------------------------------*/
  772. int polar_xy(double r, double angle, double *dx, double *dy);
  773. int xy_polar(double dx,double dy,double *radius,double *angle);
  774.  
  775. #define CSTEP (360/6)
  776. df_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
  777. {
  778.     double x0,y0,r1,a1,r2,a2,r3,a3,a4,r5,sx,sy,ex,ey;
  779.     double bx1,by1,bx2,by2,dist,neg;
  780.     g_get_xy(&x0,&y0);
  781.     xy_polar(x1-x0,y1-y0,&r1,&a1);
  782.     xy_polar(x2-x1,y2-y1,&r2,&a2);
  783.     neg = 1;
  784.     a4 = (180-a2+a1);
  785.     a3 = a2 + (a4/2);
  786.     if ((a4/2)>90 && (a4/2)<180 ) neg = -1;
  787.     if ((a4/2)<0 && (a4/2)>-90 ) neg = -1;
  788.     r3 = neg*rrr/(tan((pi/180)*a4/2));
  789.     polar_xy(-r3,a1,&sx,&sy); sx += x1; sy += y1;
  790.     polar_xy(r3,a2,&ex,&ey); ex += x1; ey += y1;
  791.     g_line(sx,sy);
  792.     dist = sqrt((ex-sx)*(ex-sx) + (ey-sy)*(ey-sy));
  793.     polar_xy(r1+ dist/2.5-r3,a1,&bx1,&by1); bx1 += x0; by1 += y0;
  794.     polar_xy(-r2+ -dist/2.5+r3,a2,&bx2,&by2); bx2 += x2; by2 += y2;
  795.     g_bezier(bx1,by1,bx2,by2,ex,ey);
  796.     g_line(x2,y2);
  797. }
  798. df_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  799. {
  800.     /* circle from t1 to t2, lets use 6 bezier's for a circle */
  801.     double stz;
  802.     int nst,i;
  803.  
  804.     for (;t2<t1;)
  805.           t2 = t2 + 360;
  806.  
  807.     nst = floor((t2-t1)/CSTEP)+1;
  808.     stz = (t2-t1) / nst;
  809.     for (i=1;i<=nst;i++)
  810.         xdf_barc(r,t1+stz*(i-1),t1+stz*i,cx,cy);
  811. }
  812. xdf_barc(double r,dbl t1,dbl t2,dbl cx,dbl cy)
  813. {
  814.     double rx1,ry1,rx2,ry2,d,dx1,dy1,dx2,dy2;
  815.  
  816.     polar_xy(r,t1,&rx1,&ry1);
  817.     polar_xy(r,t2,&rx2,&ry2);
  818.     d = sqrt( (rx2-rx1)*(rx2-rx1) + (ry2-ry1)*(ry2-ry1));
  819.     polar_xy(d/3,t1+90,&dx1,&dy1);
  820.     polar_xy(d/3,t2-90,&dx2,&dy2);
  821.     if (g.inpath) {
  822.         g_line(rx1+cx,ry1+cy);
  823.         g_bezier(rx1+cx+dx1,ry1+cy+dy1
  824.             ,rx2+cx+dx2,ry2+cy+dy2,rx2+cx,ry2+cy);
  825.     } else {
  826.         g_move(rx1+cx,ry1+cy);
  827.         g_bezier(rx1+cx+dx1,ry1+cy+dy1
  828.             ,rx2+cx+dx2,ry2+cy+dy2,rx2+cx,ry2+cy);
  829.         g_move(cx,cy);
  830.     }
  831. }
  832.  
  833. d_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
  834. {
  835.     df_arcto(x1,y1,x2,y2,rrr);
  836. }
  837. /*---------------------------------------------------------------------------*/
  838. d_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  839. {        
  840.     df_arc(r,t1,t2,cx,cy);
  841. }
  842. /*---------------------------------------------------------------------------*/
  843. d_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
  844. {
  845.     /* swap t1 and t2 */
  846.     df_arc(r,t2,t1,cx,cy);
  847. }
  848. /*---------------------------------------------------------------------------*/
  849.  
  850. /*---------------------------------------------------------------------------*/
  851. d_box_fill(dbl x1, dbl y1, dbl x2, dbl y2)
  852. {
  853.     int v[8], old_fg_color;
  854.  
  855.     old_fg_color = getcolor();
  856.     setcolor(d_fillcolor);          /* get rid of outline */
  857.  
  858.     dxy(x1,y1,&v[0],&v[1]);
  859.     dxy(x2,y1,&v[2],&v[3]);
  860.     dxy(x2,y2,&v[4],&v[5]);
  861.     dxy(x1,y2,&v[6],&v[7]);
  862.     fillpoly(4,v);
  863.  
  864.     setcolor(old_fg_color);        
  865. }
  866. d_box_stroke(dbl x1, dbl y1, dbl x2, dbl y2)
  867. {
  868.     static int ix1,iy1,ix2,iy2,ix3,iy3,ix4,iy4;
  869.     static int ii;
  870.     stop;gon;
  871.     dxy(x1,y1,&ix1,&iy1);
  872.     dxy(x2,y1,&ix2,&iy2);
  873.     dxy(x2,y2,&ix3,&iy3);
  874.     dxy(x1,y2,&ix4,&iy4);
  875.     moveto(ix1,iy1);
  876.     lineto(ix2,iy2);
  877.     lineto(ix3,iy3);
  878.     lineto(ix4,iy4);
  879.     lineto(ix1,iy1);
  880.     goff;
  881. }
  882. /*---------------------------------------------------------------------------*/
  883. d_circle_stroke(double zr)
  884. {
  885.     d_arc(zr,0,360,g.curx,g.cury);
  886. }
  887. d_circle_fill(double zr)
  888. {
  889.     int old_fg_color;
  890.  
  891.     if (!g.inpath){
  892.         old_fg_color = getcolor();
  893.         setcolor(d_fillcolor);          /* get rid of outline */
  894.         g_set_path(true);
  895.         g_newpath();
  896.         d_arc(zr,0,360,g.curx,g.cury);
  897.         g_closepath();
  898.         g_fill();
  899.         g_set_path(false);
  900.         setcolor(old_fg_color);
  901.     }
  902.     else
  903.         g_arc(zr,0,360,g.curx,g.cury);
  904. }
  905. /*---------------------------------------------------------------------------*/
  906. d_bezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
  907. {
  908.     double ax,bx,cx,ay,by,cy,dist;
  909.     double xxx,yyy,i,t,nstep,x0,y0;
  910.     g_get_xy(&x0,&y0);
  911.     dist = fabs(x3-x0) + fabs(y3-y0);
  912.     nstep = 12;
  913.     if (dist<1) nstep = 7;
  914.     if (dist<.5) nstep = 3;
  915.     if (dist<.1) {
  916.         g_line(x3,y3);
  917.         return;
  918.     }
  919.     cx = (x1-x0)*3;
  920.     bx = (x2-x1)*3-cx;
  921.     ax = x3-x0-cx-bx;
  922.     cy = (y1-y0)*3;
  923.     by = (y2-y1)*3-cy;
  924.     ay = y3-y0-cy-by;
  925.     for (i=0;i<=nstep;i++) {
  926.         t = i/nstep;
  927.         xxx = ax*pow(t,3.0) + bx*t*t + cx*t + x0;
  928.         yyy = ay*pow(t,3.0) + by*t*t + cy*t + y0;
  929.         g_line(xxx,yyy);
  930.     }
  931. }
  932. /*---------------------------------------------------------------------------*/
  933. d_set_color(int32 f)
  934. {
  935.     int i;
  936.     colortyp  cc;
  937.     stop;gon;
  938.     cc.l = f;
  939.     i = 0;
  940.     if (cc.b[B_R]>10 && cc.b[B_G]>10 && cc.b[B_B]>10) i = DARKGRAY;
  941.     if (cc.b[B_R]>60 && cc.b[B_G]>60 && cc.b[B_B]>60) i = LIGHTGRAY;
  942.     if (cc.b[B_R]>100) i = LIGHTRED;
  943.     if (cc.b[B_B]>100) i = LIGHTBLUE;
  944.     if (cc.b[B_G]>100) i = LIGHTGREEN;
  945.     if (cc.b[B_R]>100 && cc.b[B_G]>100) i = YELLOW;
  946.     if (cc.b[B_G]>100 && cc.b[B_B]>100) i = CYAN; 
  947.     if (cc.b[B_R]>30 && cc.b[B_B]>100) i = MAGENTA;
  948.     if (cc.b[B_R]>100 && cc.b[B_G]>100 && cc.b[B_B]>100) i = LIGHTGRAY;
  949.     if (cc.b[B_R]<10 && cc.b[B_G]<10 && cc.b[B_B]<10) i = BLACK; 
  950.     if (cc.b[B_R]>250 && cc.b[B_G]>250 && cc.b[B_B]>250) i = WHITE;
  951.     setcolor(i); goff;
  952. }
  953. d_set_fill(int32 f)
  954. {
  955.     int i, j;
  956.     colortyp  cc;
  957.     int ufstyle;
  958.     static char patterns[][8]={
  959.         {  24,   0,   0, 129, 129,   0,   0,  24 },     /* GRID5  */
  960.         {  60,  24, 129, 195, 195, 129,  24,  60 },     /* GRID4  */
  961.         { 231, 219, 189, 126, 126, 189, 219, 231 },     /* GRID   */
  962.         { 201, 156,  62,  62, 156, 201, 227, 227 },     /* GRID3  */
  963.         { 254, 253, 251, 247, 239, 223, 191, 127 },     /* Shade  */
  964.         { 252, 249, 243, 231, 207, 159,  63, 126 },     /* Shade2 */
  965.         { 238, 221, 187, 119, 238, 221, 187, 119 },     /* Shade1 */
  966.         { 124, 248, 241, 227, 199, 143,  31, 62 }       /* Shade3 */
  967.         };
  968.  
  969.     stop;gon;
  970.     cc.l = f;
  971.     i = j = 0;
  972.     if (cc.b[B_F] == 1){    /* colours */
  973.         if (cc.b[B_R]>=10 && cc.b[B_G]>=10 && cc.b[B_B]>=10) i = DARKGRAY;
  974.         if (cc.b[B_R]>60 && cc.b[B_G]>60 && cc.b[B_B]>60) i = LIGHTGRAY;
  975.         if (cc.b[B_R]>100) i = LIGHTRED;
  976.         if (cc.b[B_B]>100) i = LIGHTBLUE;
  977.         if (cc.b[B_G]>100) i = LIGHTGREEN;
  978.         if (cc.b[B_R]>100 && cc.b[B_G]>100) i = YELLOW;
  979.         if (cc.b[B_G]>100 && cc.b[B_B]>100) i = CYAN; 
  980.         if (cc.b[B_R]>30 && cc.b[B_B]>100) i = MAGENTA;
  981.         if (cc.b[B_R]>100 && cc.b[B_G]>100 && cc.b[B_B]>100) i = LIGHTGRAY;
  982.         if (cc.b[B_R]<10 && cc.b[B_G]<10 && cc.b[B_B]<10) i = BLACK; 
  983.         if (cc.b[B_R]>250 && cc.b[B_G]>250 && cc.b[B_B]>250) i = WHITE;
  984.         d_fillcolor = i;
  985.            }
  986.     if (cc.b[B_F] == 2){    /* grids and shades */
  987.         if (cc.b[B_R]==0x00 && cc.b[B_G]==0x20 && cc.b[B_B]==0x20) {
  988.             j = USER_FILL;  /* GRID */
  989.             ufstyle = 2;
  990.             }
  991.         if (cc.b[B_R]==0x04 && cc.b[B_G]==0x0f && cc.b[B_B]==0x0f) {
  992.             j = 11;         /* GRID1 */
  993.             ufstyle = -1;
  994.             }
  995.         if (cc.b[B_R]==0x00 && cc.b[B_G]==0x10 && cc.b[B_B]==0x10) {
  996.             j = USER_FILL;  /* GRID2 */
  997.             ufstyle = 2;
  998.             }
  999.         if (cc.b[B_R]==0x05 && cc.b[B_G]==0x20 && cc.b[B_B]==0x20) {
  1000.             j = USER_FILL;  /* GRID3 */
  1001.             ufstyle = 3;
  1002.             }
  1003.         if (cc.b[B_R]==0x10 && cc.b[B_G]==0x40 && cc.b[B_B]==0x40) {
  1004.             j = USER_FILL;  /* GRID4 */
  1005.             ufstyle = 1;
  1006.             }
  1007.         if (cc.b[B_R]==0x20 && cc.b[B_G]==0x60 && cc.b[B_B]==0x60) {
  1008.             j = USER_FILL;  /* GRID5 */
  1009.             ufstyle = 0;
  1010.             }
  1011.         if (cc.b[B_R]==0x00 && cc.b[B_G]==0x00 && cc.b[B_B]==0x20) {
  1012.             j = USER_FILL;  /* SHADE */
  1013.             ufstyle = 4;
  1014.             }
  1015.         if (cc.b[B_R]==0x04 && cc.b[B_G]==0x00 && cc.b[B_B]==0x0C) {
  1016.             j = USER_FILL;  /* SHADE1 */
  1017.             ufstyle = 6;
  1018.             }
  1019.         if (cc.b[B_R]==0x00 && cc.b[B_G]==0x00 && cc.b[B_B]==0x10) {
  1020.             j = USER_FILL;  /* SHADE2 */
  1021.             ufstyle = 5;
  1022.             }
  1023.         if (cc.b[B_R]==0x05 && cc.b[B_G]==0x00 && cc.b[B_B]==0x20) {
  1024.             j = USER_FILL;  /* SHADE3 */
  1025.             ufstyle = 7;
  1026.             }
  1027.         if (cc.b[B_R]==0x10 && cc.b[B_G]==0x00 && cc.b[B_B]==0x40) {
  1028.             j = SLASH_FILL; /* SHADE4 */
  1029.             ufstyle = -1;
  1030.             }
  1031.         if (cc.b[B_R]==0x20 && cc.b[B_G]==0x00 && cc.b[B_B]==0x60) {
  1032.             j=LTSLASH_FILL; /* SHADE5 */
  1033.             ufstyle = -1;
  1034.             }
  1035.  
  1036.         d_fillstyle = j;
  1037.         if (ufstyle != -1)
  1038.             setfillpattern( &patterns[ufstyle][0], WHITE );
  1039.         setfillstyle(d_fillstyle, WHITE );
  1040.            }
  1041.     else
  1042.            {
  1043.         d_fillstyle = SOLID_FILL;
  1044.         setfillstyle(d_fillstyle,d_fillcolor);
  1045.            }
  1046.     goff;
  1047. }
  1048. /*---------------------------------------------------------------------------*/
  1049. d_beginclip()
  1050. {
  1051. }
  1052. d_endclip()
  1053. {
  1054. }
  1055. struct char_data {float wx,wy,x1,y1,x2,y2; };
  1056. int font_get_chardata(struct char_data **cd, int ff, int cc);
  1057. /*---------------------------------------------------------------------------*/
  1058. int safnt;
  1059. int simple_char(int cc);
  1060. d_char(int font, int cc)
  1061. {
  1062.     static struct char_data cd;
  1063.     static int ix1,ix2,iy1,iy2;
  1064.     static int ux,uy;
  1065.     char ss[2];
  1066.  
  1067.     in_font = true;
  1068.     ss[0] = cc;
  1069.     ss[1] = 0;
  1070.     if (safnt==0) safnt = pass_font("PLSR");
  1071.     if (font!=82 && font>7) {
  1072.         my_char(font,cc);
  1073.         in_font = false;
  1074.         return;
  1075.     }
  1076.     if (gunit)
  1077.         simple_char(cc);
  1078.     else
  1079.         my_char(safnt,cc);
  1080.     in_font = false;
  1081. }
  1082.  
  1083. int pass_font(char *s);
  1084. int draw_char_fixed(char *s);
  1085. int get_char_pcode(int ff, int cc, char **pp);
  1086. simple_char(int cc)
  1087. {
  1088.     char *pp;
  1089.     get_char_pcode(safnt,cc,&pp);
  1090.     draw_char_fixed(pp);
  1091. }
  1092. int frxi(char **s);
  1093. draw_char_fixed(char *s)
  1094. {
  1095.     int ux,uy,cx,cy,x1,y1,x2,y2,lx,ly;
  1096.     int32 xsclm,ysclm,xscld,yscld;
  1097.     double ox,oy;
  1098.     dxy(g.curx,g.cury,&ux,&uy);
  1099.     xsclm = g.fontsz*d_xscale; xscld = 1000;
  1100.     ysclm = g.fontsz*d_yscale; yscld = 1000;
  1101.     while (*s!=15) {
  1102.       switch (*s++) {
  1103.         case 1:
  1104.         cx = frxi(&s); cy = frxi(&s);
  1105.         moveto(ux + (cx*xsclm)/xscld, uy - (cy*ysclm)/yscld );
  1106.         lx = cx; ly = cy;
  1107.         break;
  1108.         case 2:
  1109.         cx = cx + frxi(&s); cy = cy + frxi(&s);
  1110.         lineto(ux + (cx*xsclm)/xscld, uy - (cy*ysclm)/yscld );
  1111.         break;
  1112.         case 3:
  1113.         cx = cx + frxi(&s); cy = cy + frxi(&s);
  1114.         x1 = cx; y1 = cy;
  1115.         cx = cx + frxi(&s); cy = cy + frxi(&s);
  1116.         x2 = cx; y2 = cy;
  1117.         cx = cx + frxi(&s); cy = cy + frxi(&s);
  1118.         g_bezier(x1,y1,x2,y2,cx,cy);
  1119.         break;
  1120.         case 4:
  1121.         lineto(ux + (lx*xsclm)/xscld, uy - (ly*ysclm)/yscld );
  1122.         break;
  1123.         case 5:
  1124.         case 6:
  1125.         case 7:
  1126.         case 8:
  1127.         break;
  1128.         case 0: /* no char in this font */
  1129.         goto abort;
  1130.         default:
  1131.         gprint("Error in mychar pcode %d \n",*s++);
  1132.         goto abort;
  1133.       }
  1134.  
  1135.     }
  1136. abort:;
  1137. }
  1138. /*-------------------------------------------------------------------------*/
  1139.  
  1140. /*           path routines              */
  1141.  
  1142. #define PATH_LENGTH 500
  1143. struct Pnt {int type,x,y;} ;
  1144. static struct Pnt pnts[PATH_LENGTH];
  1145. static int npnts;
  1146. enum {P_MOVE,P_LINE,P_BEZIER};
  1147. static int startx,starty;
  1148. void path_move(int x, int y)
  1149. {
  1150.     startx = x; starty = y;
  1151.     pnts[npnts].type = P_MOVE;
  1152.     pnts[npnts].x = x;
  1153.     pnts[npnts++].y = y;
  1154. }
  1155. void path_line(int x, int y)
  1156. {
  1157.     pnts[npnts].type = P_LINE;
  1158.     pnts[npnts].x = x;
  1159.     pnts[npnts++].y = y;
  1160. }
  1161. void path_close(void)
  1162. {
  1163.     pnts[npnts].type = P_LINE;
  1164.     pnts[npnts].x = startx;
  1165.     pnts[npnts++].y = starty;
  1166. }
  1167. void path_fill(void)
  1168. {
  1169.     int pts[2*PATH_LENGTH];
  1170.     int i,npts;
  1171.  
  1172.     for (i=0; i<npnts; i++) 
  1173.        {
  1174.         if (pnts[i].type==P_LINE)
  1175.           {
  1176.             npts = 0;
  1177.             pts[npts++] = pnts[i].x;
  1178.             pts[npts++] = pnts[i++].y;
  1179.             for (;pnts[i].type==P_LINE && i<npnts;i++)
  1180.                {
  1181.                 pts[npts++] = pnts[i].x;
  1182.                 pts[npts++] = pnts[i].y;
  1183.                }
  1184.             pts[npts++] = pts[0]; /* close polygon */
  1185.             pts[npts++] = pts[1];
  1186.             fillpoly(npts/2,pts);
  1187.           }
  1188.        }
  1189. }
  1190. void path_newpath(void)
  1191. {
  1192.     npnts = 0;
  1193. }
  1194. void path_stroke(void)
  1195. {
  1196.     for (i=1; i<npnts; i++) 
  1197.            {
  1198.         if (pnts[i].type==P_LINE) 
  1199.             {
  1200.              line(pnts[i-1].x, pnts[i-1].y,
  1201.                   pnts[i].x,   pnts[i].y);
  1202.             }
  1203.            }
  1204. }
  1205.